﻿using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace dPet.Web.Hospital.Controllers
{
	using dPet.Application.DataObjects;
	using dPet.Application.QueryObjects;
	using dPet.Application.Services;
	using dPet.Web.Hospital.Fliters;
	using dPet.Web.Hospital.ViewModels;
	using Hangerd.Mvc;
	using Hangerd.Utility;

	public class AjaxController : HangerdController
	{
		private readonly IProductManagementService _productManagementService;
		private readonly IInventoryService _invoicingService;
		private readonly ISalesService _salesService;
		private readonly IServiceManagementService _serviceManagementService;
		private readonly IServingService _servingService;

		public AjaxController(
			IProductManagementService productManagementService,
			IInventoryService invoicingService,
			ISalesService salesService,
			IServiceManagementService serviceManagementService,
			IServingService servingService)
		{
			_productManagementService = productManagementService;
			_invoicingService = invoicingService;
			_salesService = salesService;
			_serviceManagementService = serviceManagementService;
			_servingService = servingService;
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult ProductSubCategoryList(string categoryId)
		{
			var subCategories = _productManagementService.GetProductSubCategories(categoryId)
				.Select(sc => new
				{
					Id = sc.Id,
					Name = sc.Name
				});

			return JsonContent(subCategories);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult ProductList(ProductQueryDto queryDto)
		{
			var totalNumber = 0;
			var products = _productManagementService.GetProducts(LoginStaffModel.Current.HospitalId, false, false, queryDto, 1, 10, out totalNumber)
				.Select(product => new
				{
					Id = product.Id,
					Barcode = product.Barcode,
					Name = product.Name,
					UnitName = product.UnitName
				});

			return JsonContent(products);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult ProductListForMembership(ProductQueryDto queryDto, MembershipLevelDto membershipLevel = MembershipLevelDto.None)
		{
			var products = _productManagementService.GetProductsForMembership(LoginStaffModel.Current.HospitalId, membershipLevel, queryDto)
				.Select(product => new
				{
					Id = product.Id,
					Barcode = product.Barcode,
					Name = product.Name,
					UnitPrice = product.UnitPrice,
					UnitName = product.UnitName,
					InventoryCount = product.Inventories.Sum(i => i.Quantity)
				});

			return JsonContent(products);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult ProductInventories(string productId)
		{
			var product = _productManagementService.GetProduct(productId, false, true);
			var inventories = product == null || product.Inventories == null
				? null
				: product.Inventories.Where(i => i.Quantity > 0).OrderBy(i => i.ExpiryTime)
					.Select(i => new
					{
						ProductId = productId,
						InventoryNumber = i.InventoryNumber,
						ExpiryTime = i.ExpiryTime.ToString("yyyy-MM-dd"),
						Quantity = i.Quantity,
						LoType = InventoryLOTypeDto.Loss.ToString(),
						Amount = 0
					});

			return JsonContent(inventories);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "{\"Total\":0, \"Alarms\":[]}")]
		public ActionResult InventoryAlarmsForHeader()
		{
			var totalNumber = 0;
			var alarms = _invoicingService.GetInventoryAlarms(LoginStaffModel.Current.HospitalId, 1, 5, out totalNumber)
				.Select(alarm => new
				{
					Id = alarm.Id,
					AlarmType = alarm.AlarmType,
					Title = string.Format("商品 [{0}（{1}）] {2}，点击查看", alarm.ProductName, alarm.ProductBarcode, alarm.Detail),
					TitleCut = string.Format("{0}：{1}", CommonTools.GetEnumDescription(alarm.AlarmType), CommonTools.CutString(alarm.ProductName, 10, ".."))
				});

			return JsonContent(new { Total = totalNumber, Alarms = alarms });
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult InventoryBatchDetails(string batchId)
		{
			var batch = _invoicingService.GetInventoryBatch(batchId);
			var batchDetail = batch == null || batch.Details == null
				? null
				: batch.Details.OrderBy(b => b.ExpiryTime).Select(b => new
				{
					BatchNumber = batch.BatchNumber,
					ProductId = b.ProductId,
					ProductBarcode = b.ProductBarcode,
					ProductName = b.ProductName,
					Quantity = b.Quantity,
					UnitName = b.UnitName,
					ExpiryTime = b.ExpiryTime.ToString("yyyy-MM-dd")
				});

			return JsonContent(batchDetail);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult SaleOrderDetails(string orderId)
		{
			var order = _salesService.GetSaleOrder(orderId);
			var orderDetails = order == null || order.OrderLines == null
				? null
				: order.OrderLines.Select(o => new
				{
					OrderNumber = order.OrderNumber,
					ProductBarcode = o.ProductBarcode,
					ProductName = o.ProductName,
					UnitPrice = o.UnitPrice,
					UnitName = o.UnitName,
					Quantity = o.Quantity
				});

			return JsonContent(orderDetails);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult ServiceItems(string categoryId)
		{
			var serviceItems = _serviceManagementService.GetServiceItemsByCategory(categoryId)
				.Select(si => new
				{
					Id = si.Id,
					Name = si.Name
				});

			return JsonContent(serviceItems);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult ServiceSKUPropertyValues(string propertyId)
		{
			var property = _serviceManagementService.GetServiceSKUProperty(propertyId, false, true);
			var propertyValues = property == null || property.Values == null
				? null
				: property.Values.Select(v => new
				{
					Id = v.Id,
					Value = v.Value,
					LastModified = v.LastModified.ToString("yyyy-MM-dd HH:mm:ss")
				});

			return JsonContent(propertyValues);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "{\"ExistProperties\":[],\"LeftProperties\":[]}")]
		public ActionResult ServiceItemSKUPropertoes(string serviceItemId)
		{
			var serviceItem = _serviceManagementService.GetServiceItem(serviceItemId, true, true, false);
			var existProperties = serviceItem == null || serviceItem.SKUProperties == null
				? null
				: serviceItem.SKUProperties.Select(p => new
				{
					Id = p.Id,
					FrontendName = p.FrontendName,
					BackendName = p.BackendName
				});

			var totalProperties = _serviceManagementService.GetServiceSKUPropertiesByCategory(serviceItem.Category.Id);
			var leftProperties = new List<dynamic>();

			foreach (var property in totalProperties)
			{
				if (serviceItem.SKUProperties.Count(p => p.Id == property.Id) == 0)
				{
					leftProperties.Add(new
					{
						Id = property.Id,
						FrontendName = property.FrontendName,
						BackendName = property.BackendName
					});
				}
			}

			return JsonContent(new
			{
				ExistProperties = existProperties,
				LeftProperties = leftProperties
			});
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult ServiceItemSKUList(string serviceItemId)
		{
			var serviceItem = _serviceManagementService.GetServiceItem(serviceItemId, false, false, true);
			var skuList = serviceItem == null || serviceItem.SKUList == null
				? null
				: serviceItem.SKUList.Select(isku => new
				{
					Id = isku.Id,
					SKUPropertyValueNames = isku.SKUPropertyValueNames,
					UnitPrice = isku.UnitPrice
				});

			return JsonContent(skuList);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult ServiceItemSKUListForMembership(string serviceItemId, MembershipLevelDto membershipLevel = MembershipLevelDto.None)
		{
			var skuList = _serviceManagementService.GetServiceItemSKUListForMembership(serviceItemId, membershipLevel)
				.Select(isku => new
				{
					Id = isku.Id,
					ServiceItemName = isku.ServiceItem.Name,
					SKUPropertyValueNames = isku.SKUPropertyValueNames,
					UnitPrice = isku.UnitPrice
				});

			return JsonContent(skuList);
		}

		[HttpPost]
		[StaffLoginAuth(Ajax = true, DefaultAjaxResult = "[]")]
		public ActionResult ServiceOrderDetails(string orderId)
		{
			var order = _servingService.GetServiceOrder(orderId);
			var orderDetails = order == null || order.OrderLines == null
				? null
				: order.OrderLines.Select(o => new
				{
					OrderNumber = order.OrderNumber,
					ServiceItemName = o.ServiceItemName,
					SKUPropertyValueNames = o.SKUPropertyValueNames,
					UnitPrice = o.UnitPrice,
					Quantity = o.Quantity
				});

			return JsonContent(orderDetails);
		}
	}
}
